package xin.fsqr520.project.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import xin.fsqr520.project.domain.dto.AddCommentRequest;
import xin.fsqr520.project.domain.dto.PostDTO;
import xin.fsqr520.project.domain.po.*;
import xin.fsqr520.project.domain.vo.*;
import xin.fsqr520.project.mapper.*;
import xin.fsqr520.project.service.IFriendShipService;
import xin.fsqr520.project.service.IPostCommentService;
import xin.fsqr520.project.service.IPostLikeService;

import javax.validation.Valid;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 动态相关的控制器，处理动态相关的HTTP请求
 */
@RestController
@RequestMapping("/post")
public class PostController {


    @Autowired
    private PostMapper postMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private PostLikeMapper postLikeMapper;

    @Autowired
    private PostCommentMapper postCommentMapper;

    @Autowired
    private IPostCommentService postCommentService;

    @Autowired
    private IFriendShipService friendShipService;

    @Autowired
    private IPostLikeService postLikeService;

    /**
     * 查询评论过userId的帖子的人的列表信息
     *
     * @param userId
     * @return
     */
    @GetMapping("/CommentUserList")
    private Result<?> getCommentUserLists(Long userId) {
        //先查询userId的所有帖子id
        List<Post> postIdList = postMapper.selectList(new LambdaQueryWrapper<Post>().eq(Post::getUserId, userId).select(Post::getPostId, Post::getImageUrls));
        if (postIdList == null) return Result.success();
        List<PostCommentVO> result = new ArrayList<>();
        //查询帖子的评论id
        for (Post post : postIdList) {
            Long postId = post.getPostId();
            //查询哪些人给这个帖子点赞了
            List<PostComment> commentUserIdList = postCommentMapper.selectList(
                    new LambdaQueryWrapper<PostComment>()
                            .eq(PostComment::getPostId, postId).select(PostComment::getUserId, PostComment::getCommentContent, PostComment::getCreatedAt)
            );
            //查询该用户的信息
            for (PostComment liekUser : commentUserIdList) {
                //自己给自己评论不管
                if (Objects.equals(liekUser.getUserId(), userId)) continue;
                User user = userMapper.selectById(liekUser.getUserId());
                PostCommentVO r = PostCommentVO.builder()
                        .commentUserName(user.getUsername()).commentUserAvatar(user.getAvatar())
                        .commentContent(liekUser.getCommentContent()).commentTime(liekUser.getCreatedAt().toString())
                        .commentPostUrl(getOneUrl(post.getImageUrls())).build();

                result.add(r);
            }
        }
        return Result.success(result);
    }

    /**
     * 查询点赞过userId的帖子的人的列表信息
     *
     * @param userId
     * @return
     */
    @GetMapping("/LikeUserList")
    private Result<?> getLikeUserLists(Long userId) {
        //先查询userId的所有帖子id
        List<Post> postIdList = postMapper.selectList(new LambdaQueryWrapper<Post>().eq(Post::getUserId, userId).select(Post::getPostId, Post::getImageUrls));
        if (postIdList == null) return Result.success();
        List<PostLikeVo> result = new ArrayList<>();
        //查询帖子的点赞id
        for (Post post : postIdList) {
            Long postId = post.getPostId();
            //查询哪些人给这个帖子点赞了
            List<PostLike> likeUserIdList = postLikeMapper.selectList(
                    new LambdaQueryWrapper<PostLike>()
                            .eq(PostLike::getPostId, postId).select(PostLike::getUserId, PostLike::getCreatedAt)
            );
            //查询该用户的信息
            for (PostLike liekUser : likeUserIdList) {
                //自己给自己点赞不管
                if (Objects.equals(liekUser.getUserId(), userId)) continue;
                User user = userMapper.selectById(liekUser.getUserId());
                PostLikeVo r = PostLikeVo.builder()
                        .likeUserName(user.getUsername()).likeUserAvatar(user.getAvatar())
                        .likeTime(liekUser.getCreatedAt().toString()).likePostUrl(getOneUrl(post.getImageUrls())).build();
                result.add(r);
            }
        }
        return Result.success(result);
    }

    private String getOneUrl(String imageUrls) {
        if (imageUrls == null || imageUrls.isBlank()) return "";
        return imageUrls.split("\\|")[0];
    }

    /**
     * 点赞 /取消点赞
     *
     * @return
     */
    @PutMapping("/likeOrUnlike")
    public Result<?> likeOrUnlike(Long userId, Long postId, Boolean flag) {
        if (userId == null || postId == null || flag == null) return Result.error("信息不完善");
        int i = postLikeService.likeOrUnlike(userId, postId, flag);
        if (i == 1) {
            if (flag) return Result.success("点赞成功");
            return Result.success("取消点赞成功");
        }
        if (flag) return Result.success("点赞失败");
        return Result.success("点赞失败");
    }

    /**
     * 根据话题查询动态
     *
     * @param userId
     * @return
     */
    @GetMapping("/getPostsByTopic")
    public Result<Object> getPostByTopic(Long userId, String topic) {
        if (topic == null || topic.isBlank()) return Result.error("话题不能为空");
        //先查询所有帖子
        LambdaQueryWrapper<Post> wrapper = new LambdaQueryWrapper<Post>()
                .eq(Post::getTopic, topic)
                .orderByDesc(Post::getCreatedAt);//先展示最新的
        List<Post> list = postMapper.selectList(wrapper);
        if (list == null) return Result.success(Collections.emptyList());

        List<PostVO> res = new ArrayList<>(list.size());
        for (Post cur : list) {
            long postHostId = cur.getUserId();//帖子发布者id
            long postid = cur.getPostId();
            //查询发帖者用户信息
            User user = userMapper.selectById(postHostId);

            //查询用户是否对某个动态点赞过
            boolean flag = hasLiked(postid, userId);//查看用户是否点赞过要看请求者

            PostVO postVO = PostVO.builder()
                    .postId(postid)
                    .userId(postHostId)
                    .avatar(user.getAvatar())
                    .username(user.getUsername())
                    .timeAgo(calculateTimeAgo(cur.getCreatedAt()))
                    .content(cur.getContent())
                    .images(parseImages(cur.getImageUrls()))//用到的图片
                    .likes(cur.getLikeCount())//点赞数
                    .comments(cur.getCommentCount())
                    .shares(cur.getShareCount())
                    .Liked(flag)//当前用户是否点赞过
                    .topic(cur.getTopic())
                    .build();
            res.add(postVO);
        }
        return Result.success(res);
    }

    /**
     * 查询当前关注了的人发的动态 并返回前端需要的格式
     *
     * @param userId
     * @return
     */
    @GetMapping("/getEmployPosts")
    public Result<Object> getEmployPosts(Long userId) {
        //先查询所有帖子
        LambdaQueryWrapper<Post> wrapper = new LambdaQueryWrapper<Post>()
                .orderByDesc(Post::getCreatedAt);//先展示最新的
        List<Post> list = postMapper.selectList(wrapper);
        if (list == null) return Result.success(Collections.emptyList());

        List<PostVO> res = new ArrayList<>(list.size());
        for (Post cur : list) {
            long postHostId = cur.getUserId();//帖子发布者id
            long postid = cur.getPostId();
            //查询发帖者用户信息
            User user = userMapper.selectById(postHostId);

            //如果关注了才继续
            LambdaQueryWrapper<Friendship> wrapper1 = new LambdaQueryWrapper<Friendship>()
                    .eq(Friendship::getUserId, userId).eq(Friendship::getFriendId, postHostId);
            long i = friendShipService.count(wrapper1);
            if (i != 1) continue;//没关注 就不管

            //查询用户是否对某个动态点赞过
            boolean flag = hasLiked(postid, userId);//查看用户是否点赞过要看请求者

            PostVO postVO = PostVO.builder()
                    .postId(postid)
                    .userId(postHostId)
                    .avatar(user.getAvatar())
                    .username(user.getUsername())
                    .timeAgo(calculateTimeAgo(cur.getCreatedAt()))
                    .content(cur.getContent())
                    .images(parseImages(cur.getImageUrls()))//用到的图片
                    .likes(cur.getLikeCount())//点赞数
                    .comments(cur.getCommentCount())
                    .shares(cur.getShareCount())
                    .Liked(flag)//当前用户是否点赞过
                    .topic(cur.getTopic())
                    .build();
            res.add(postVO);
        }
        return Result.success(res);
    }

    /**
     * 获取(当前)用户的获赞数 粉丝数 关注数
     *
     * @param userid
     * @return
     */
    @GetMapping("/numbers")
    public Result<?> getNums(Long userid) {
        //粉丝->哪些人的好友列表有我
        long fansCount = friendShipService.count(
                new LambdaQueryWrapper<Friendship>().eq(Friendship::getFriendId, userid)
        );
        //关注->我的好友列表有哪些人
        long follow = friendShipService.count(
                new LambdaQueryWrapper<Friendship>().eq(Friendship::getUserId, userid)
        );
        //获赞数
        long likeCount = postMapper.getLikeCountByUserId(userid);

        // 用 Map 封装结果
        Map<String, Object> data = new HashMap<>();
        data.put("fansCount", fansCount);
        data.put("follow", follow);
        data.put("likeCount", likeCount);

        return Result.success(data); // 假设你有一个通用的 Result.success() 方法
    }


    /**
     * 查询userId用户的主页信息 包含个人信息 动态数量 粉丝数量 关注数量 发的动态
     *
     * @param userId
     * @return
     */
    @GetMapping("/getHomeDetail")
    public Result<?> getHomePage(Long userId, Long curUserId) {
        if (userId == null || curUserId == null) return Result.error("请求参数不正确");
        //1.先查询userId的用户信息
        User user = userMapper.selectById(userId);
        if (user == null) return Result.error("用户不存在?查询出错");

        //2.查询粉丝数量 关注数量
        //粉丝->哪些人的还有列表有我
        long fansCount = friendShipService.count(new LambdaQueryWrapper<Friendship>().eq(Friendship::getFriendId, userId));
        //关注->我的还有列表有哪些人
        long likeCount = friendShipService.count(new LambdaQueryWrapper<Friendship>().eq(Friendship::getUserId, userId));

        //3.查找userid发布的动态相关数据
        //先查询所有帖子
        LambdaQueryWrapper<Post> wrapper = new LambdaQueryWrapper<Post>()
                .orderByDesc(Post::getCreatedAt).eq(Post::getUserId, userId);//先展示最新的
        List<Post> list = postMapper.selectList(wrapper);
        List<PostVO> res = null;
        if (list != null) {
            res = new ArrayList<>(list.size());
            for (Post cur : list) {
                long postid = cur.getPostId();
                //查询用户是否对某个动态点赞过
                boolean flag = hasLiked(postid, curUserId);//查看当前用户是否点赞过要看请求者

                PostVO postVO = PostVO.builder()
                        .postId(postid)
                        .userId(userId)
                        .avatar(user.getAvatar())
                        .username(user.getUsername())
                        .timeAgo(calculateTimeAgo(cur.getCreatedAt()))
                        .content(cur.getContent())
                        .images(parseImages(cur.getImageUrls()))//用到的图片
                        .likes(cur.getLikeCount())//点赞数
                        .comments(cur.getCommentCount())
                        .shares(cur.getShareCount())
                        .Liked(flag)//当前用户是否点赞过
                        .topic(cur.getTopic())
                        .build();
                res.add(postVO);
            }
        }

        //4.组装
        HomePageVO homePageVO = HomePageVO.builder()
                .userAvatar(user.getAvatar()).username(user.getUsername()).grade(user.getGrade())
                .college(user.getSchool()).major(user.getSpecialty()).postCount(list == null ? 0 : list.size())
                .fanCount(fansCount).followCount(likeCount).postVOList(res).build();

        return Result.success(homePageVO);
    }

    /**
     * 添加帖子
     *
     * @return
     */
//    @CacheEvict(value = "allPosts", allEntries = true)
    @PostMapping("/publishPost")
    public Result<Object> addPost(@Valid @RequestBody PostDTO postDTO) {
        /**
         * 使用valid注解配合实体类的notnull还有全局异常处理可以简化参数校验
         * 注意需要引入validation依赖
         */

        Post post = Post.builder()
                .userId(postDTO.getUserId())
                .content(postDTO.getContent())
                .imageUrls(joinImageUrls(postDTO.getImages()))
                .topic(postDTO.getTopic())
                .likeCount(0)
                .commentCount(0)
                .shareCount(0)
                .createdAt(LocalDateTime.now())
                .build();
        int i = postMapper.insert(post);
        if (i == 1) return Result.success(post);
        return Result.error("发布失败");
    }

    /**
     * 给帖子添加评论
     *
     * @return
     */
//    @CacheEvict(value = "allPosts", allEntries = true)
//todo  不对 给帖子加评论不应该删除所有帖子的数量cache啊 最多影响评论数 点赞数啥的 无所谓 要是微服务就好了
    @PutMapping("/addCommentToPost")
    public Result<Object> addComment(@RequestBody AddCommentRequest request) {
        //包含帖子id 评论者id 评论内容 评论的父评论(这里先考虑只有一级评论 parentId=1)

        if (request.getParentId() != 0L) return Result.error("暂时只支持一级评论");
        int status = postCommentService.addComment(request.getUserId(), request.getPostId(), request.getContent(), 0L);//需要操作两个表 稍微用一下事务
        if (status == 1) return Result.success("评论发送成功");
        System.out.println(status);
        return Result.error("评论发送失败");
    }
/*    为什么微服务更好？
    微服务可以把帖子列表、评论、点赞等功能拆开成不同服务，各自管理自己的缓存。
    比如评论服务只管理评论缓存，帖子服务只管理帖子列表缓存，互不干扰。
    这样评论变更只清理评论缓存，不影响帖子列表，系统更清晰、性能更优。*/

    /**
     * 查询所有动态 并返回前端需要的格式
     *
     * @param userId
     * @return
     */
//    @Cacheable(value = "allPosts", key = "'post_list_' + #userId")//生成的key是allPosts::post_list_42
    @GetMapping("/getAllPosts")
    public Result<Object> getAllPosts(Long userId) {
        //先查询所有帖子
        LambdaQueryWrapper<Post> wrapper = new LambdaQueryWrapper<Post>()
                .orderByDesc(Post::getCreatedAt);//先展示最新的
        List<Post> list = postMapper.selectList(wrapper);
        if (list == null) return Result.success(Collections.emptyList());

        List<PostVO> res = new ArrayList<>(list.size());
        for (Post cur : list) {
            long postHostId = cur.getUserId();//帖子发布者id
            long postid = cur.getPostId();
            //查询发帖者用户信息
            User user = userMapper.selectById(postHostId);

            //查询用户是否对某个动态点赞过
            boolean flag = hasLiked(postid, userId);//查看用户是否点赞过要看请求者

            PostVO postVO = PostVO.builder()
                    .postId(postid)
                    .userId(postHostId)
                    .avatar(user.getAvatar())
                    .username(user.getUsername())
                    .timeAgo(calculateTimeAgo(cur.getCreatedAt()))
                    .content(cur.getContent())
                    .images(parseImages(cur.getImageUrls()))//用到的图片
                    .likes(cur.getLikeCount())//点赞数
                    .comments(cur.getCommentCount())
                    .shares(cur.getShareCount())
                    .Liked(flag)//当前用户是否点赞过
                    .topic(cur.getTopic())
                    .build();
            res.add(postVO);
        }
        return Result.success(res);
    }

    /**
     * 获取动态详情
     *
     * @param postId
     * @return
     */
    @GetMapping("/getPostDetail")
//    @Cacheable(value = "postDetail", key = "'post_' + #postId + '_user_' + #userId")
    //不好根据 post_postId_id缓存来删除啊 算了~~
    public Result<Object> getPostDetail(Long postId) {
        //1.先查到当前动态
        Post post = postMapper.selectById(postId);
        if (post == null) return Result.error("有问题?");
        //帖子主人
        Long userId = post.getUserId();
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<User>()
                .eq(User::getId, userId)
                .select(User::getUsername, User::getAvatar);
        User postUser = userMapper.selectOne(userLambdaQueryWrapper);
        if (postUser == null) return Result.error("有问题!");

        //2.查询动态下的评论

        LambdaQueryWrapper<PostComment> wrapper = new LambdaQueryWrapper<PostComment>()
                .eq(PostComment::getPostId, postId)
                .orderByDesc(PostComment::getCreatedAt);//先看最新的评论

        List<PostComment> comments = postCommentMapper.selectList(wrapper);

        //3.补充一些字段
        for (PostComment cur : comments) {
            Long postcommentUserId = cur.getUserId();//评论的用户ID
            User postCommentUser = userMapper.selectById(postcommentUserId);
            cur.setUserAvatar(postCommentUser.getAvatar());
            cur.setUserName(postCommentUser.getUsername());
            cur.setTimeago(calculateTimeAgo(cur.getCreatedAt()));
        }

        //4.组装返回前端的
        PostDetailVO postDetailVO = PostDetailVO.builder()
                .postId(post.getPostId()).userId(post.getUserId()).avatar(postUser.getAvatar())
                .username(postUser.getUsername()).timeAgo(calculateTimeAgo(post.getCreatedAt()))
                .content(post.getContent()).images(parseImages(post.getImageUrls())).likes(post.getLikeCount())
                .comments(post.getCommentCount()).shares(post.getShareCount())
                .Liked(hasLiked(postId, userId)).commentList(comments).build();


        return Result.success(postDetailVO);
    }

    /**
     * 安全拼接图片URL列表，使用|作为分隔符
     *
     * @param images 图片URL列表
     * @return 拼接后的字符串，如"url1|url2|url3"
     */
    public static String joinImageUrls(List<String> images) {
        if (images == null || images.isEmpty()) {
            return "";
        }

        // 使用StringJoiner指定分隔符
        StringJoiner joiner = new StringJoiner("|");
        for (String url : images) {
            // 可以在这里添加对URL的空值判断
            if (url != null) {
                joiner.add(url);
            }
        }
        return joiner.toString();
    }

    public boolean hasLiked(Long postId, Long userId) {
        // 构建查询条件：post_id = ? AND user_id = ?
        QueryWrapper<PostLike> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("post_id", postId)
                .eq("user_id", userId);

        // 查询是否存在记录（利用唯一索引，效率极高）
        PostLike postLike = postLikeMapper.selectOne(queryWrapper);

        // 存在则返回true，否则返回false
        return postLike != null;
    }

    private List<String> parseImages(String imageUrls) {
        // 处理null和空字符串
        if (imageUrls == null || imageUrls.trim().isEmpty()) {
            return Collections.emptyList(); // 返回空列表而非null，
        }

        // 拆分并过滤空元素
        return Arrays.stream(imageUrls.split("\\|"))// 注意split方法需要转义，因为|是正则特殊字符
                .map(String::trim) // 去除前后空格
                .filter(s -> !s.isEmpty()) // 过滤空字符串
                .collect(Collectors.toList());
    }


    /**
     * 计算多少**之前
     *
     * @param createdAt
     * @return
     */
    private static String calculateTimeAgo(LocalDateTime createdAt) {
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();

        // 计算分钟差
        long minutes = ChronoUnit.MINUTES.between(createdAt, now);

        // 1小时以内（60分钟），返回分钟前
        if (minutes < 60) {
            return minutes + "分钟前";
        }

        // 计算小时差
        long hours = ChronoUnit.HOURS.between(createdAt, now);

        // 1天以内（24小时），返回小时前
        if (hours < 24) {
            return hours + "小时前";
        }

        // 超过1天，返回天前
        long days = ChronoUnit.DAYS.between(createdAt, now);
        return days + "天前";
    }

}